package com.nuanshui.heatedloan.middleware.fastjson;

import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.nuanshui.framework.utils.ReflectionUtils;
import com.nuanshui.heatedloan.middleware.fastjson.annotation.FastjsonIgnore;

/**
 * 解析fastjson 注解  过滤给 客户端序列化时不必要的字段
 * @param 
 * @author guohao
 * @date 2017年2月10日 下午2:23:46
 * @since $
 */
public class FastjsonIgnoreFilter implements PropertyPreFilter {

	
	@JSONField
	 private final Class<?> clazz;
	 private final Set<String> excludes = new HashSet<String>();
	 
	 private final static ConcurrentHashMap<String,Boolean> filedSerialize  = new ConcurrentHashMap<String,Boolean>();
	 
	 
	 public FastjsonIgnoreFilter(String... properties) {
		 this(null, properties);
		 
	 }
	 public FastjsonIgnoreFilter(Class<?> clazz, String... properties) {
		    super();
	        this.clazz = clazz;
	        for (String item : properties) {
	            if (item != null) {
	                this.excludes.add(item);
	            }
	        }
	 }
	@Override
	public boolean apply(JSONSerializer serializer, Object object, String name) {		
		try {
			serializer.config(SerializerFeature.WriteDateUseDateFormat, false);
	        if (object == null) {
	            return true;
	        }

	        if (clazz != null && !clazz.isInstance(object)) {
	            return true;
	        }

	        
	        if (this.excludes.contains(name)) {
	            return false;
	        }
	        String key = new StringBuffer(object.getClass().getName()).append(".").append(name).toString();
	        Boolean serialize = filedSerialize.get(key);
	        if(serialize!=null) return serialize;
		    Field field = 	ReflectionUtils.getAccessibleField(object, name);    
		    if(field!=null && field.isAnnotationPresent(FastjsonIgnore.class)) {
		    	filedSerialize.put(key, false);
		    	return false;
		    }
		    filedSerialize.put(key, true);
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return true;
	}

}
